package com.xiyoukt.springboot.interceptor;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.NamedThreadLocal;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.text.SimpleDateFormat;

// 拦截器是单例的，所有请求都使用同一个拦截器
public class AccessLogInterceptor implements HandlerInterceptor {

    private Logger log = LoggerFactory.getLogger(AccessLogInterceptor.class);

    private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");

    private static final ThreadLocal<Long> requestTimeThreadLocal = new NamedThreadLocal<>("request time");

    /**
     * 请求处理之前调用
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String ip = getRomoteIp(request);
        Long startTime = System.currentTimeMillis();
        requestTimeThreadLocal.set(startTime);
        log.info("IP {} - sessionId {} - 请求时间 {} - 请求地址 {}",
                ip, request.getSession().getId(), sdf.format(startTime), request.getRequestURI());

//        if(request.getSession().getAttribute("user") == null){
//            response.sendRedirect("/login");
//            return false;
//        }

        return true;
    }

    private String getRomoteIp(HttpServletRequest request){
        if(request.getHeader("x-forwarded-for") == null){
            return request.getRemoteAddr();
        }
        return request.getHeader("x-forwarded-for");
    }

    /**
     * 在请求处理之后，且视图渲染之前调用
     * @param request
     * @param response
     * @param handler
     * @param modelAndView
     * @throws Exception
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        if(modelAndView == null){
            log.info("请求处理完成");
        }else{
            log.info("请求处理完成，开始渲染视图 {}", modelAndView.getViewName());
        }
    }

    /**
     * 在整个请求完成之后调用
     * @param request
     * @param response
     * @param handler
     * @param ex
     * @throws Exception
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        Long startTime = requestTimeThreadLocal.get();
        Long endTime = System.currentTimeMillis();
        String ip = getRomoteIp(request);
        Long processTime = endTime - startTime;
        log.info("IP {} - sessionId {} - 请求时间 {} - 请求地址 {} - 处理时间 {}ms",
                ip, request.getSession().getId(), sdf.format(startTime), request.getRequestURI(), processTime);
        if(processTime > 500){
            // 记录慢请求到文件中
        }
    }
}
